#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
匹配算法服务 - 提供基础的用户匹配功能
"""

from typing import Dict, List, Optional, Any, Tuple
import json
import math
from app.models.user_profile import UserProfile
from app.models.mate_criteria import MateCriteria
from app.services.dict_service import DictService


class MatchingService:
    """匹配算法服务类"""
    
    # 匹配权重配置
    MATCH_WEIGHTS = {
        # 基础条件匹配权重
        'age_range': 0.20,           # 年龄范围匹配权重
        'education': 0.15,           # 教育程度匹配权重
        'occupation': 0.10,          # 职业匹配权重
        'income': 0.15,              # 收入匹配权重
        'location': 0.10,            # 地区匹配权重
        
        # 生活习惯匹配权重
        'marital_status': 0.10,      # 婚姻状况匹配权重
        'housing_status': 0.05,      # 住房情况匹配权重
        'car_status': 0.03,          # 车辆情况匹配权重
        'smoking_habit': 0.05,       # 吸烟习惯匹配权重
        'drinking_habit': 0.05,      # 饮酒习惯匹配权重
        
        # 兴趣爱好匹配权重
        'personality_traits': 0.02,  # 性格特点匹配权重（加分项）
        'hobbies': 0.02             # 兴趣爱好匹配权重（加分项）
    }
    
    @classmethod
    def calculate_match_score(cls, user_id: int, target_user_id: int) -> Dict[str, Any]:
        """
        计算两个用户之间的匹配度评分
        
        Args:
            user_id: 当前用户ID
            target_user_id: 目标用户ID
            
        Returns:
            包含匹配评分和详细信息的字典
        """
        try:
            # 获取用户资料
            user_profile = UserProfile.query.filter_by(user_id=user_id).first()
            target_profile = UserProfile.query.filter_by(user_id=target_user_id).first()
            
            if not user_profile or not target_profile:
                return {
                    'match_score': 0.0,
                    'error': '用户资料不完整'
                }
            
            # 获取择偶条件
            user_criteria = MateCriteria.query.filter_by(user_id=user_id).first()
            
            # 计算各项匹配度
            match_details = {}
            total_score = 0.0
            max_possible_score = 0.0
            
            # 年龄匹配
            age_score, age_detail = cls._calculate_age_match(user_criteria, target_profile)
            match_details['age'] = age_detail
            total_score += age_score * cls.MATCH_WEIGHTS['age_range']
            max_possible_score += cls.MATCH_WEIGHTS['age_range']
            
            # 教育程度匹配
            education_score, education_detail = cls._calculate_education_match(user_criteria, target_profile)
            match_details['education'] = education_detail
            total_score += education_score * cls.MATCH_WEIGHTS['education']
            max_possible_score += cls.MATCH_WEIGHTS['education']
            
            # 收入匹配
            income_score, income_detail = cls._calculate_income_match(user_criteria, target_profile)
            match_details['income'] = income_detail
            total_score += income_score * cls.MATCH_WEIGHTS['income']
            max_possible_score += cls.MATCH_WEIGHTS['income']
            
            # 婚姻状况匹配
            marital_score, marital_detail = cls._calculate_marital_match(user_criteria, target_profile)
            match_details['marital_status'] = marital_detail
            total_score += marital_score * cls.MATCH_WEIGHTS['marital_status']
            max_possible_score += cls.MATCH_WEIGHTS['marital_status']
            
            # 生活习惯匹配
            smoking_score, smoking_detail = cls._calculate_smoking_match(user_criteria, target_profile)
            match_details['smoking_habit'] = smoking_detail
            total_score += smoking_score * cls.MATCH_WEIGHTS['smoking_habit']
            max_possible_score += cls.MATCH_WEIGHTS['smoking_habit']
            
            drinking_score, drinking_detail = cls._calculate_drinking_match(user_criteria, target_profile)
            match_details['drinking_habit'] = drinking_detail
            total_score += drinking_score * cls.MATCH_WEIGHTS['drinking_habit']
            max_possible_score += cls.MATCH_WEIGHTS['drinking_habit']
            
            # 兴趣爱好匹配（加分项）
            hobby_score, hobby_detail = cls._calculate_hobby_match(user_profile, target_profile)
            match_details['hobbies'] = hobby_detail
            total_score += hobby_score * cls.MATCH_WEIGHTS['hobbies']
            
            # 性格特点匹配（加分项）
            personality_score, personality_detail = cls._calculate_personality_match(user_profile, target_profile)
            match_details['personality_traits'] = personality_detail
            total_score += personality_score * cls.MATCH_WEIGHTS['personality_traits']
            
            # 计算最终匹配度（百分制）
            if max_possible_score > 0:
                match_percentage = (total_score / max_possible_score) * 100
            else:
                match_percentage = 0.0
            
            return {
                'match_score': round(match_percentage, 2),
                'total_score': round(total_score, 4),
                'max_possible_score': round(max_possible_score, 4),
                'match_details': match_details,
                'user_id': user_id,
                'target_user_id': target_user_id
            }
            
        except Exception as e:
            return {
                'match_score': 0.0,
                'error': f'计算匹配度失败: {str(e)}'
            }
    
    @classmethod
    def _calculate_age_match(cls, criteria: Optional[MateCriteria], profile: UserProfile) -> Tuple[float, Dict]:
        """计算年龄匹配度"""
        if not criteria or not criteria.min_age or not criteria.max_age or not profile.age:
            return 0.0, {'score': 0.0, 'reason': '年龄信息不完整'}
        
        target_age = profile.age
        min_age = criteria.min_age
        max_age = criteria.max_age
        
        if min_age <= target_age <= max_age:
            # 在理想范围内，根据接近中心值的程度给分
            center_age = (min_age + max_age) / 2
            distance = abs(target_age - center_age)
            range_half = (max_age - min_age) / 2
            
            if range_half > 0:
                score = 1.0 - (distance / range_half) * 0.3  # 最低0.7分
            else:
                score = 1.0
            
            return score, {
                'score': round(score, 2),
                'target_age': target_age,
                'preferred_range': f'{min_age}-{max_age}',
                'status': '匹配'
            }
        else:
            # 不在范围内，根据偏离程度扣分
            if target_age < min_age:
                distance = min_age - target_age
            else:
                distance = target_age - max_age
            
            # 偏离越远分数越低，最低0分
            score = max(0.0, 1.0 - distance * 0.1)
            
            return score, {
                'score': round(score, 2),
                'target_age': target_age,
                'preferred_range': f'{min_age}-{max_age}',
                'status': '不匹配'
            }
    
    @classmethod
    def _calculate_education_match(cls, criteria: Optional[MateCriteria], profile: UserProfile) -> Tuple[float, Dict]:
        """计算教育程度匹配度"""
        if not criteria or not criteria.education_requirements or not profile.education:
            return 0.5, {'score': 0.5, 'reason': '教育信息不完整，给予中等分数'}
        
        # 解析教育要求
        requirements = DictService.parse_json_dict_values(criteria.education_requirements)
        
        if profile.education in requirements:
            return 1.0, {
                'score': 1.0,
                'target_education': DictService.get_dict_text_by_value('education', profile.education),
                'requirements': DictService.format_dict_values_text('education', requirements),
                'status': '完全匹配'
            }
        else:
            return 0.3, {
                'score': 0.3,
                'target_education': DictService.get_dict_text_by_value('education', profile.education),
                'requirements': DictService.format_dict_values_text('education', requirements),
                'status': '不匹配'
            }
    
    @classmethod
    def _calculate_income_match(cls, criteria: Optional[MateCriteria], profile: UserProfile) -> Tuple[float, Dict]:
        """计算收入匹配度"""
        if not criteria or not criteria.income_requirements or not profile.income_range:
            return 0.5, {'score': 0.5, 'reason': '收入信息不完整，给予中等分数'}
        
        # 解析收入要求
        requirements = DictService.parse_json_dict_values(criteria.income_requirements)
        
        if profile.income_range in requirements:
            return 1.0, {
                'score': 1.0,
                'target_income': DictService.get_dict_text_by_value('income_range', profile.income_range),
                'requirements': DictService.format_dict_values_text('income_requirement', requirements),
                'status': '完全匹配'
            }
        else:
            # 根据收入等级差异给分
            score = cls._calculate_income_level_score(profile.income_range, requirements)
            return score, {
                'score': score,
                'target_income': DictService.get_dict_text_by_value('income_range', profile.income_range),
                'requirements': DictService.format_dict_values_text('income_requirement', requirements),
                'status': '部分匹配' if score > 0.3 else '不匹配'
            }
    
    @classmethod
    def _calculate_marital_match(cls, criteria: Optional[MateCriteria], profile: UserProfile) -> Tuple[float, Dict]:
        """计算婚姻状况匹配度"""
        if not criteria or not criteria.marital_requirements or not profile.marital_status:
            return 0.5, {'score': 0.5, 'reason': '婚姻状况信息不完整，给予中等分数'}
        
        # 解析婚姻状况要求
        requirements = DictService.parse_json_dict_values(criteria.marital_requirements)
        
        if profile.marital_status in requirements:
            return 1.0, {
                'score': 1.0,
                'target_status': DictService.get_dict_text_by_value('marital_status', profile.marital_status),
                'requirements': DictService.format_dict_values_text('marital_requirement', requirements),
                'status': '完全匹配'
            }
        else:
            return 0.2, {
                'score': 0.2,
                'target_status': DictService.get_dict_text_by_value('marital_status', profile.marital_status),
                'requirements': DictService.format_dict_values_text('marital_requirement', requirements),
                'status': '不匹配'
            }
    
    @classmethod
    def _calculate_smoking_match(cls, criteria: Optional[MateCriteria], profile: UserProfile) -> Tuple[float, Dict]:
        """计算吸烟习惯匹配度"""
        if not criteria or not criteria.smoking_requirements or not profile.smoking_habit:
            return 0.8, {'score': 0.8, 'reason': '吸烟习惯信息不完整，给予较高分数'}
        
        # 解析吸烟习惯要求
        requirements = DictService.parse_json_dict_values(criteria.smoking_requirements)
        
        if profile.smoking_habit in requirements:
            return 1.0, {
                'score': 1.0,
                'target_habit': DictService.get_dict_text_by_value('smoking_habit', profile.smoking_habit),
                'requirements': DictService.format_dict_values_text('smoking_requirement', requirements),
                'status': '完全匹配'
            }
        else:
            return 0.4, {
                'score': 0.4,
                'target_habit': DictService.get_dict_text_by_value('smoking_habit', profile.smoking_habit),
                'requirements': DictService.format_dict_values_text('smoking_requirement', requirements),
                'status': '不匹配'
            }
    
    @classmethod
    def _calculate_drinking_match(cls, criteria: Optional[MateCriteria], profile: UserProfile) -> Tuple[float, Dict]:
        """计算饮酒习惯匹配度"""
        if not criteria or not criteria.drinking_requirements or not profile.drinking_habit:
            return 0.8, {'score': 0.8, 'reason': '饮酒习惯信息不完整，给予较高分数'}
        
        # 解析饮酒习惯要求
        requirements = DictService.parse_json_dict_values(criteria.drinking_requirements)
        
        if profile.drinking_habit in requirements:
            return 1.0, {
                'score': 1.0,
                'target_habit': DictService.get_dict_text_by_value('drinking_habit', profile.drinking_habit),
                'requirements': DictService.format_dict_values_text('drinking_requirement', requirements),
                'status': '完全匹配'
            }
        else:
            return 0.4, {
                'score': 0.4,
                'target_habit': DictService.get_dict_text_by_value('drinking_habit', profile.drinking_habit),
                'requirements': DictService.format_dict_values_text('drinking_requirement', requirements),
                'status': '不匹配'
            }
    
    @classmethod
    def _calculate_hobby_match(cls, user_profile: UserProfile, target_profile: UserProfile) -> Tuple[float, Dict]:
        """计算兴趣爱好匹配度（加分项）"""
        if not user_profile.hobby_tags or not target_profile.hobby_tags:
            return 0.0, {'score': 0.0, 'reason': '兴趣爱好信息不完整'}
        
        # 解析兴趣爱好标签
        user_hobbies = set(DictService.parse_json_dict_values(user_profile.hobby_tags))
        target_hobbies = set(DictService.parse_json_dict_values(target_profile.hobby_tags))
        
        if not user_hobbies or not target_hobbies:
            return 0.0, {'score': 0.0, 'reason': '兴趣爱好标签为空'}
        
        # 计算交集比例
        common_hobbies = user_hobbies.intersection(target_hobbies)
        total_hobbies = user_hobbies.union(target_hobbies)
        
        if total_hobbies:
            score = len(common_hobbies) / len(total_hobbies)
        else:
            score = 0.0
        
        return score, {
            'score': round(score, 2),
            'common_hobbies': DictService.format_dict_values_text('hobbies', list(common_hobbies)),
            'common_count': len(common_hobbies),
            'total_count': len(total_hobbies),
            'status': '有共同爱好' if common_hobbies else '无共同爱好'
        }
    
    @classmethod
    def _calculate_personality_match(cls, user_profile: UserProfile, target_profile: UserProfile) -> Tuple[float, Dict]:
        """计算性格特点匹配度（加分项）"""
        if not user_profile.personality_traits or not target_profile.personality_traits:
            return 0.0, {'score': 0.0, 'reason': '性格特点信息不完整'}
        
        # 解析性格特点标签
        user_traits = set(DictService.parse_json_dict_values(user_profile.personality_traits))
        target_traits = set(DictService.parse_json_dict_values(target_profile.personality_traits))
        
        if not user_traits or not target_traits:
            return 0.0, {'score': 0.0, 'reason': '性格特点标签为空'}
        
        # 计算互补和相似性
        common_traits = user_traits.intersection(target_traits)
        total_traits = user_traits.union(target_traits)
        
        if total_traits:
            # 性格既要有相似性也要有互补性
            similarity_score = len(common_traits) / len(total_traits)
            complementary_score = (len(total_traits) - len(common_traits)) / len(total_traits)
            # 取平衡值
            score = (similarity_score + complementary_score * 0.3) / 1.3
        else:
            score = 0.0
        
        return score, {
            'score': round(score, 2),
            'common_traits': DictService.format_dict_values_text('personality_traits', list(common_traits)),
            'common_count': len(common_traits),
            'total_count': len(total_traits),
            'status': '性格互补' if score > 0.5 else '性格一般'
        }
    
    @classmethod
    def _calculate_income_level_score(cls, target_income: str, requirement_incomes: List[str]) -> float:
        """根据收入等级差异计算匹配分数"""
        # 收入等级映射（数值越高收入越高）
        income_levels = {
            'income_3k_below': 1,    # 3000以下
            'income_3k_5k': 2,       # 3000-5000
            'income_5k_8k': 3,       # 5000-8000
            'income_8k_12k': 4,      # 8000-12000
            'income_12k_20k': 5,     # 12000-20000
            'income_20k_30k': 6,     # 20000-30000
            'income_30k_above': 7    # 30000以上
        }
        
        target_level = income_levels.get(target_income, 0)
        requirement_levels = [income_levels.get(req, 0) for req in requirement_incomes]
        
        if not requirement_levels:
            return 0.5
        
        # 计算与要求收入等级的最小差距
        min_distance = min(abs(target_level - req_level) for req_level in requirement_levels)
        
        # 根据差距给分：0差距=1.0分，1差距=0.8分，2差距=0.6分，以此类推
        score = max(0.0, 1.0 - min_distance * 0.2)
        
        return score 

    @classmethod
    def intelligent_match(cls, user_id: int, page: int = 1, per_page: int = 20, 
                         filter_options: Dict[str, Any] = None) -> Dict[str, Any]:
        """
        智能匹配算法 - 根据用户画像和择偶条件智能推荐
        
        Args:
            user_id: 当前用户ID
            page: 页码
            per_page: 每页数量
            filter_options: 筛选选项
            
        Returns:
            匹配结果
        """
        try:
            from app.models.user import User
            from app import db
            
            filter_options = filter_options or {}
            min_score = filter_options.get('min_score', 60)
            location_priority = filter_options.get('location_priority', False)
            online_recently = filter_options.get('online_recently', False)
            
            # 获取用户信息
            current_user = User.query.get(user_id)
            if not current_user:
                return {'success': False, 'error': '用户不存在'}
            
            # 构建基础查询
            query = User.query.filter(
                User.id != user_id,
                User.status == 1,  # 正常状态用户
                User.profile_complete == 1  # 资料完整用户
            )
            
            # 如果启用同城优先
            if location_priority and current_user.city:
                # 优先同城，然后是同省，最后是其他地区
                same_city_query = query.filter(User.city == current_user.city)
                same_province_query = query.filter(
                    User.province == current_user.province,
                    User.city != current_user.city
                )
                other_users_query = query.filter(
                    User.province != current_user.province
                )
            else:
                same_city_query = query
                same_province_query = None
                other_users_query = None
            
            # 获取候选用户
            candidates = []
            
            # 同城用户
            if same_city_query:
                same_city_users = same_city_query.limit(per_page * 2).all()
                candidates.extend(same_city_users)
            
            # 如果同城用户不够，补充同省用户
            if same_province_query and len(candidates) < per_page:
                remaining = per_page * 2 - len(candidates)
                same_province_users = same_province_query.limit(remaining).all()
                candidates.extend(same_province_users)
            
            # 如果还不够，补充其他地区用户
            if other_users_query and len(candidates) < per_page:
                remaining = per_page * 2 - len(candidates)
                other_users = other_users_query.limit(remaining).all()
                candidates.extend(other_users)
            
            # 计算匹配度并筛选
            matches = []
            for candidate in candidates:
                match_result = cls.calculate_match_score(user_id, candidate.id)
                
                if 'error' not in match_result and match_result['match_score'] >= min_score:
                    user_data = candidate.to_dict()
                    user_data['match_score'] = match_result['match_score']
                    user_data['match_details'] = match_result['match_details']
                    user_data['match_level'] = cls._get_match_level(match_result['match_score'])
                    matches.append(user_data)
            
            # 按匹配度排序
            matches.sort(key=lambda x: x['match_score'], reverse=True)
            
            # 分页处理
            start_index = (page - 1) * per_page
            end_index = start_index + per_page
            page_matches = matches[start_index:end_index]
            
            total = len(matches)
            pages = math.ceil(total / per_page) if per_page > 0 else 1
            
            return {
                'success': True,
                'data': {
                    'matches': page_matches,
                    'pagination': {
                        'page': page,
                        'pages': pages,
                        'per_page': per_page,
                        'total': total,
                        'has_next': page < pages,
                        'has_prev': page > 1
                    },
                    'filter_applied': filter_options
                }
            }
            
        except Exception as e:
            return {'success': False, 'error': f'智能匹配失败: {str(e)}'}
    
    @classmethod
    def batch_calculate_match_scores(cls, user_id: int, target_user_ids: List[int], 
                                   algorithm_type: str = 'advanced') -> Dict[str, Any]:
        """
        批量计算匹配度
        
        Args:
            user_id: 当前用户ID
            target_user_ids: 目标用户ID列表
            algorithm_type: 算法类型
            
        Returns:
            批量计算结果
        """
        try:
            results = []
            
            for target_id in target_user_ids:
                match_result = cls.calculate_match_score(user_id, target_id)
                
                if 'error' not in match_result:
                    results.append({
                        'target_user_id': target_id,
                        'match_score': match_result['match_score'],
                        'match_level': cls._get_match_level(match_result['match_score']),
                        'algorithm_type': algorithm_type
                    })
                else:
                    results.append({
                        'target_user_id': target_id,
                        'match_score': 0.0,
                        'match_level': '计算失败',
                        'error': match_result['error']
                    })
            
            # 按匹配度排序
            results.sort(key=lambda x: x['match_score'], reverse=True)
            
            return {
                'batch_results': results,
                'total_calculated': len(results),
                'average_score': sum(r['match_score'] for r in results) / len(results) if results else 0,
                'algorithm_type': algorithm_type
            }
            
        except Exception as e:
            return {'error': f'批量计算失败: {str(e)}'}
    
    @classmethod
    def generate_match_recommendations(cls, user_id: int, recommendation_type: str = 'daily',
                                     count: int = 10, diversity_factor: float = 0.3) -> Dict[str, Any]:
        """
        生成个性化匹配推荐
        
        Args:
            user_id: 用户ID
            recommendation_type: 推荐类型
            count: 推荐数量
            diversity_factor: 多样性因子
            
        Returns:
            推荐结果
        """
        try:
            from app.models.user import User
            
            # 根据推荐类型设置不同策略
            strategies = {
                'daily': {'min_score': 50, 'diversity': True, 'location_weight': 1.5},
                'weekly': {'min_score': 60, 'diversity': True, 'location_weight': 1.2},
                'premium': {'min_score': 70, 'diversity': False, 'location_weight': 1.0},
                'nearby': {'min_score': 40, 'diversity': True, 'location_weight': 2.0}
            }
            
            strategy = strategies.get(recommendation_type, strategies['daily'])
            
            # 获取候选用户
            candidates = User.query.filter(
                User.id != user_id,
                User.status == 1,
                User.profile_complete == 1
            ).limit(count * 5).all()  # 获取更多候选用户以保证推荐质量
            
            recommendations = []
            
            for candidate in candidates:
                match_result = cls.calculate_match_score(user_id, candidate.id)
                
                if 'error' not in match_result and match_result['match_score'] >= strategy['min_score']:
                    user_data = candidate.to_dict()
                    user_data['match_score'] = match_result['match_score']
                    user_data['match_level'] = cls._get_match_level(match_result['match_score'])
                    user_data['recommendation_reason'] = cls._generate_recommendation_reason(match_result)
                    recommendations.append(user_data)
            
            # 多样性处理
            if strategy['diversity'] and len(recommendations) > count:
                recommendations = cls._apply_diversity_filter(recommendations, count, diversity_factor)
            
            # 按匹配度排序并截取指定数量
            recommendations.sort(key=lambda x: x['match_score'], reverse=True)
            recommendations = recommendations[:count]
            
            return {
                'success': True,
                'data': {
                    'recommendations': recommendations,
                    'recommendation_type': recommendation_type,
                    'total_count': len(recommendations),
                    'strategy_applied': strategy
                }
            }
            
        except Exception as e:
            return {'success': False, 'error': f'生成推荐失败: {str(e)}'}
    
    @classmethod
    def get_algorithms_info(cls) -> Dict[str, Any]:
        """获取可用匹配算法信息"""
        return {
            'algorithms': [
                {
                    'type': 'basic',
                    'name': '基础匹配算法',
                    'description': '基于基本条件的匹配',
                    'features': ['年龄匹配', '地区匹配', '基本偏好']
                },
                {
                    'type': 'advanced',
                    'name': '高级匹配算法',
                    'description': '综合多维度的智能匹配',
                    'features': ['全维度匹配', '权重优化', '智能推荐']
                },
                {
                    'type': 'ai',
                    'name': 'AI匹配算法',
                    'description': '基于机器学习的智能匹配',
                    'features': ['行为分析', '偏好学习', '个性化推荐']
                }
            ],
            'weights': cls.MATCH_WEIGHTS,
            'current_version': '2.0'
        }
    
    @classmethod
    def get_user_matching_statistics(cls, user_id: int) -> Dict[str, Any]:
        """获取用户匹配统计信息"""
        try:
            from app.models.user import User
            
            # 获取基础统计
            total_users = User.query.filter(User.id != user_id, User.status == 1).count()
            
            # 模拟统计数据（实际应该从数据库或缓存中获取）
            return {
                'total_potential_matches': total_users,
                'high_match_count': int(total_users * 0.15),
                'medium_match_count': int(total_users * 0.35),
                'low_match_count': int(total_users * 0.50),
                'average_match_score': 65.8,
                'last_calculation_time': '2025-07-10 22:00:00',
                'recommendation_refresh_interval': '24小时'
            }
            
        except Exception as e:
            return {'error': f'获取统计失败: {str(e)}'}
    
    @classmethod
    def get_user_matching_preferences(cls, user_id: int) -> Dict[str, Any]:
        """获取用户匹配偏好设置"""
        # 这里应该从数据库中获取用户的匹配偏好设置
        # 暂时返回默认设置
        return {
            'algorithm_preference': 'advanced',
            'diversity_factor': 0.3,
            'location_priority': True,
            'minimum_score_threshold': 60,
            'daily_recommendation_count': 10,
            'notification_enabled': True
        }
    
    @classmethod
    def update_user_matching_preferences(cls, user_id: int, preferences: Dict[str, Any]) -> Dict[str, Any]:
        """更新用户匹配偏好设置"""
        try:
            # 验证偏好设置
            valid_algorithms = ['basic', 'advanced', 'ai']
            
            if 'algorithm_preference' in preferences:
                if preferences['algorithm_preference'] not in valid_algorithms:
                    return {'success': False, 'error': '无效的算法类型'}
            
            if 'diversity_factor' in preferences:
                if not 0 <= preferences['diversity_factor'] <= 1:
                    return {'success': False, 'error': '多样性因子应在0-1之间'}
            
            if 'minimum_score_threshold' in preferences:
                if not 0 <= preferences['minimum_score_threshold'] <= 100:
                    return {'success': False, 'error': '最低分数阈值应在0-100之间'}
            
            # 这里应该保存到数据库
            # 暂时返回更新成功
            updated_preferences = cls.get_user_matching_preferences(user_id)
            updated_preferences.update(preferences)
            
            return {
                'success': True,
                'data': updated_preferences,
                'message': '匹配偏好更新成功'
            }
            
        except Exception as e:
            return {'success': False, 'error': f'更新失败: {str(e)}'}
    
    @classmethod
    def get_detailed_match_calculation(cls, user_id: int, target_user_id: int) -> Dict[str, Any]:
        """获取详细的匹配分数计算过程（调试用）"""
        try:
            match_result = cls.calculate_match_score(user_id, target_user_id)
            
            # 添加更多调试信息
            debug_info = {
                'calculation_process': match_result,
                'algorithm_weights': cls.MATCH_WEIGHTS,
                'calculation_steps': {
                    'step1': '获取用户资料和择偶条件',
                    'step2': '计算各维度匹配度',
                    'step3': '应用权重计算总分',
                    'step4': '转换为百分制分数'
                },
                'optimization_suggestions': cls._get_optimization_suggestions(match_result)
            }
            
            return debug_info
            
        except Exception as e:
            return {'error': f'获取调试信息失败: {str(e)}'}
    
    @classmethod
    def _get_match_level(cls, score: float) -> str:
        """根据分数获取匹配等级"""
        if score >= 85:
            return '极高匹配'
        elif score >= 75:
            return '高度匹配'
        elif score >= 65:
            return '中等匹配'
        elif score >= 50:
            return '一般匹配'
        else:
            return '匹配度较低'
    
    @classmethod
    def _generate_recommendation_reason(cls, match_result: Dict[str, Any]) -> str:
        """生成推荐理由"""
        try:
            score = match_result.get('match_score', 0)
            details = match_result.get('match_details', {})
            
            reasons = []
            
            # 分析高分维度
            for dimension, detail in details.items():
                if isinstance(detail, dict) and detail.get('score', 0) >= 0.8:
                    if dimension == 'age':
                        reasons.append('年龄匹配度高')
                    elif dimension == 'education':
                        reasons.append('学历要求符合')
                    elif dimension == 'income':
                        reasons.append('收入水平匹配')
                    # 添加更多维度的推荐理由
            
            if score >= 80:
                return f"高度匹配用户，{', '.join(reasons[:2])}"
            elif score >= 60:
                return f"匹配度良好，{', '.join(reasons[:1])}"
            else:
                return "可以了解一下"
                
        except:
            return "系统推荐"
    
    @classmethod
    def _apply_diversity_filter(cls, recommendations: List[Dict], count: int, diversity_factor: float) -> List[Dict]:
        """应用多样性筛选"""
        if len(recommendations) <= count:
            return recommendations
        
        # 简单的多样性算法：确保不同教育背景、职业等的用户都有机会被推荐
        diversified = []
        used_educations = set()
        used_occupations = set()
        
        # 按匹配度排序
        sorted_recs = sorted(recommendations, key=lambda x: x['match_score'], reverse=True)
        
        for rec in sorted_recs:
            if len(diversified) >= count:
                break
                
            education = rec.get('education', '')
            occupation = rec.get('occupation', '')
            
            # 多样性检查
            diversity_score = 0
            if education not in used_educations:
                diversity_score += 1
            if occupation not in used_occupations:
                diversity_score += 1
            
            # 根据多样性因子决定是否添加
            if diversity_score > 0 or len(diversified) < count * (1 - diversity_factor):
                diversified.append(rec)
                used_educations.add(education)
                used_occupations.add(occupation)
        
        return diversified
    
    @classmethod
    def _get_optimization_suggestions(cls, match_result: Dict[str, Any]) -> List[str]:
        """获取匹配度优化建议"""
        suggestions = []
        details = match_result.get('match_details', {})
        
        for dimension, detail in details.items():
            if isinstance(detail, dict) and detail.get('score', 0) < 0.5:
                if dimension == 'age':
                    suggestions.append('考虑调整年龄偏好范围')
                elif dimension == 'education':
                    suggestions.append('考虑放宽学历要求')
                elif dimension == 'income':
                    suggestions.append('考虑调整收入期望')
                # 添加更多优化建议
        
        if not suggestions:
            suggestions.append('当前择偶条件设置合理')
        
        return suggestions 